﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Cust = RentAWorker.Business.Tests.CustomerProxy;
using Ref = RentAWorker.Business.Tests.RefDataProxy;
using Rent = RentAWorker.Business.Tests.RentRequestProxy;
using Requ = RentAWorker.Business.Tests.RequestMgmtProxy;
using Res = RentAWorker.Business.Tests.ResourceMgmtProxy;
using Dsp = RentAWorker.Business.Tests.DataServiceProxy;
using System.Configuration;

namespace RentAWorker.Business.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class ProxyTests
    {
        private Cust.CustomerServiceClient Customer;
        private Cust.ManageCustomerServiceClient CustomerMgmt;
        private Ref.ReferenceDataServiceClient RefData;
        private Rent.RentRequestServiceClient RentRequest;
        private Requ.ManageRequestServiceClient RequestMgmt;
        private Res.ManageResourceServiceClient ResourceMgmt;
        private Dsp.BigDays2009EntitiesSimple DataServiceEntities;

        public ProxyTests()
        {
            Customer = new RentAWorker.Business.Tests.CustomerProxy.CustomerServiceClient();
            CustomerMgmt = new RentAWorker.Business.Tests.CustomerProxy.ManageCustomerServiceClient();
            RefData = new RentAWorker.Business.Tests.RefDataProxy.ReferenceDataServiceClient();
            RentRequest = new RentAWorker.Business.Tests.RentRequestProxy.RentRequestServiceClient();
            RequestMgmt = new RentAWorker.Business.Tests.RequestMgmtProxy.ManageRequestServiceClient();
            ResourceMgmt = 
                new RentAWorker.Business.Tests.ResourceMgmtProxy.ManageResourceServiceClient
                    (
                        "BasicHttpBinding_IManageResourceService"
                    );
            DataServiceEntities = new RentAWorker.Business.Tests.DataServiceProxy.BigDays2009EntitiesSimple
                                  (
                                    new Uri(ConfigurationManager.AppSettings["dspUri"])
                                  );

            DataServiceEntities.Credentials =
            Customer.ClientCredentials.Windows.ClientCredential =
            CustomerMgmt.ClientCredentials.Windows.ClientCredential =
            RefData.ClientCredentials.Windows.ClientCredential =
            RentRequest.ClientCredentials.Windows.ClientCredential =
            RequestMgmt.ClientCredentials.Windows.ClientCredential =
            ResourceMgmt.ClientCredentials.Windows.ClientCredential =
                (System.Net.NetworkCredential)System.Net.CredentialCache.DefaultCredentials;
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void CustomersGetAll()
        {
            TestContext.WriteLine("Retrieving customers...");

            Cust.Customer[] Customers = CustomerMgmt.GetCustomers(string.Empty);
            TestContext.WriteLine("Called successfully!");
            foreach (var c in Customers)
            {
                TestContext.WriteLine("Getting details for {0}...", c.CustomerID);
                Cust.Customer cd = Customer.GetCustomer(c.CustomerID);
                TestContext.WriteLine("Details retrieved: {0} {1}!", cd.Name, cd.MembershipID);

                TestContext.WriteLine("Getting by membership ID...");
                int cdId = Customer.GetCustomerForUser(
                    cd.MembershipID == null ? Guid.Empty : cd.MembershipID.Value);
                TestContext.WriteLine("Customer ID by Membership retrieved: {0}!", cdId);

                TestContext.WriteLine("-----");
            }
        }

        [TestMethod]
        public void ManageRequestsGetRentalServices()
        {
            TestContext.WriteLine("Retrieving rental service requests...");
            string[] Stati = new string[] { "Pending", "Accepted", "Declined" };
            foreach (var Status in Stati)
            {
                TestContext.WriteLine("for status {0}", Status);
                Requ.RentalService[] Services = RequestMgmt.GetRentalServicesForManager(Status);
                foreach (var Service in Services)
                {
                    TestContext.WriteLine("-) {0} {1} {2} {3}",
                        Service.Customer.Name,
                        Service.Resource.Name,
                        Service.StartDate,
                        Service.EndDate);
                }
            }
            TestContext.WriteLine("Done!");
        }

        [TestMethod]
        public void ManageRequestApproveService()
        {
            TestContext.WriteLine("Finding first 'pending' request...");
            Requ.RentalService[] Services = RequestMgmt.GetRentalServicesForManager("Pending");
            if (Services.Length > 0)
            {
                RequestMgmt.ApproveRentalService(Services[0].RentalServiceID);
                TestContext.WriteLine("Done!");
            }
            else
            {
                Assert.Inconclusive("No 'pending' requests available!");
            }
        }

        [TestMethod]
        public void ManageRequestDeclineService()
        {
            TestContext.WriteLine("Finding first 'pending' request...");
            Requ.RentalService[] Services = RequestMgmt.GetRentalServicesForManager("Pending");
            if (Services.Length > 0)
            {
                RequestMgmt.RejectRentalService(Services[0].RentalServiceID);
                TestContext.WriteLine("Done!");
            }
            else
            {
                Assert.Inconclusive("No 'pending' requests available!");
            }
        }

        [TestMethod]
        public void RequestNewRentalService()
        {
            TestContext.WriteLine("Requesting new Rental Service...");
            
            // Get the first customer
            TestContext.WriteLine("Retrieving customer...");
            Cust.Customer RentCustomer = Customer.GetCustomer(1);
            Assert.IsNotNull(RentCustomer, "No customer available in services!");

            // Next get the rent resource
            TestContext.WriteLine("Retrieving resource...");
            Res.RentResource RentRes = ResourceMgmt.GetResource(1);
            Assert.IsNotNull(RentRes, "No resource available in services!");

            // Request the resource for a specific date
            TestContext.WriteLine("Requesting resource...");
            Rent.RentalServiceRequest Request = new RentAWorker.Business.Tests.RentRequestProxy.RentalServiceRequest();
            Request.CustomerId = 1;
            Request.ResourceId = 1;
            Request.LocationId = RentRes.Location.LocationID;
            Request.FromDate = DateTime.Now.AddDays(10);
            Request.ToDate = DateTime.Now.AddDays(15);
            Request.CancelRequest = false;
            Rent.RentalServiceResponse Response = RentRequest.RequestRentalService(Request);

            TestContext.WriteLine("Call done!");
            TestContext.WriteLine("Response: {0} {1}", Response.Succeeded, Response.Information);
            TestContext.WriteLine("Done!");
        }

        [TestMethod]
        public void ManageResourceGetAll()
        {
            TestContext.WriteLine("Retrieving all machines...");
            Res.RentResource[] ResourcesA = ResourceMgmt.GetResourcesByLocation(string.Empty, Res.ResourceType.Machine);
            TestContext.WriteLine("Retrieving all workers...");
            Res.RentResource[] ResourcesB = ResourceMgmt.GetResourcesByLocation(string.Empty, Res.ResourceType.Worker);
            IEnumerable<Res.RentResource> Resources = ResourcesA.Concat(ResourcesB);
            foreach (var r in Resources)
            {
                TestContext.WriteLine("Found Resource: {0} {1} {2}",
                    r.Name, r.ResourceID, r.GetType().Name);
            }

            TestContext.WriteLine("Done!");
        }

        [TestMethod]
        public void DataServicesProxyTest()
        {
            TestContext.WriteLine("Retrieving Locations...");

            var Locations = from l in DataServiceEntities.Location
                            select l;
            foreach (var l in Locations)
            {
                TestContext.WriteLine("Found location: {0} {1}!!", l.LocationID, l.LocationName);
                if (l.LocationName.Contains("_test_"))
                    l.LocationName = l.LocationName.Replace("_test_", "");
                else
                    l.LocationName = l.LocationName + "_test_";

                TestContext.WriteLine("- try updating location");
                try
                {
                    DataServiceEntities.UpdateObject(l);
                    DataServiceEntities.SaveChanges();
                    TestContext.WriteLine("- update succeeded");
                }
                catch (Exception ex)
                {
                    TestContext.WriteLine("- update failed: {0}", ex.Message);
                }
            }

            TestContext.WriteLine("Done!");
        }
    }
}
